﻿// Released to the public domain. Use, modify and relicense at will.

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
using BeginMode = OpenTK.Graphics.OpenGL.BeginMode;
using BlendEquationMode = OpenTK.Graphics.OpenGL.BlendEquationMode;
using BlendingFactorDest = OpenTK.Graphics.OpenGL.BlendingFactorDest;
using BlendingFactorSrc = OpenTK.Graphics.OpenGL.BlendingFactorSrc;
using ClearBufferMask = OpenTK.Graphics.OpenGL.ClearBufferMask;
using EnableCap = OpenTK.Graphics.OpenGL.EnableCap;
using GL = OpenTK.Graphics.OpenGL.GL;
using MatrixMode = OpenTK.Graphics.OpenGL.MatrixMode;

namespace _2D_Game
{
    class Game : GameWindow
    {
        public static int[] Dimensions = new[] {800, 600};
        public static int X = 0, Y = 1;

        /// <summary>Creates a 800x600 window with the specified title.</summary>
        public Game()
            : base(Dimensions[X], Dimensions[Y], GraphicsMode.Default, "_2D_Game Quick Start Sample")
        {
            VSync = VSyncMode.On;
        }

        /// <summary>Load resources here.</summary>
        /// <param name="e">Not used.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);
            GL.Enable(EnableCap.DepthTest);

            //_squ = new Square[20];
            //string file = ".\\tiles\\land\\top.png";
            //for (int i = 0; i < _squ.Length; i++)
            //{
            //    _squ[i] = new Square(100 + 32 * i, 400, 32, 32);
            //    _squ[i].SetTexture(TextureManager.LoadTexture(file));
            //}
            //_squ[0].SetTexture(TextureManager.LoadTexture(".\\tiles\\land\\topleft.png"));
            //_squ[_squ.Length - 1].SetTexture(TextureManager.LoadTexture(".\\tiles\\land\\topright.png"));

            _level = Level.ParseXml("..\\..\\Levels\\Level1.xml");
        }

        //private Square[] _squ;
        private Level _level;

        /// <summary>
        /// Called when your window is resized. Set your viewport here. It is also
        /// a good place to set up your projection matrix (which probably changes
        /// along when the aspect ratio of your window).
        /// </summary>
        /// <param name="e">Not used.</param>
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);

            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)System.Math.PI / 4, Width / (float)Height, 1.0f, 64.0f);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);
        }

        /// <summary>
        /// Called when it is time to setup the next frame. Add you game logic here.
        /// </summary>
        /// <param name="e">Contains timing information for framerate independent logic.</param>
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            base.OnUpdateFrame(e);

            if (Keyboard[Key.Escape])
                Exit();
        }

        /// <summary>
        /// Called when it is time to render the next frame. Add your rendering code here.
        /// </summary>
        /// <param name="e">Contains timing information.</param>
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);

            GL.ClearColor(Color.Black);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(0, Dimensions[X], Dimensions[Y], 0, -1, 1);
            GL.Viewport(0, 0, Dimensions[X], Dimensions[Y]);

            //foreach (var s in _squ)
            //{
            //    s.Render();
            //}
            _level.Render();
            GL.Begin(BeginMode.Points);
            GL.Vertex2(100, 100);
            GL.End();

            GL.Flush();
            this.SwapBuffers();  
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            // The 'using' idiom guarantees proper resource cleanup.
            // We request 30 UpdateFrame events per second, and unlimited
            // RenderFrame events (as fast as the computer can handle).
            using (var game = new Game())
            {
                game.Run(30.0);
            }
        }
    }
}